package com.ruoyi.course.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.student.domain.vo.CourseSchedulingIinquiryVo;
import com.ruoyi.trainingManagement.domain.ClassScheduleDetailed;
import com.ruoyi.trainingManagement.domain.CourseScheduleDetails;
import com.ruoyi.trainingManagement.mapper.ClassScheduleDetailedMapper;
import com.ruoyi.trainingManagement.mapper.CourseScheduleDetailsMapper;
import com.ruoyi.trainingManagement.mapper.CourseStudentInfoMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.course.mapper.ResourceAvailabilityMapper;
import com.ruoyi.course.domain.ResourceAvailability;
import com.ruoyi.course.domain.vo.TimetableVO;
import com.ruoyi.course.service.IResourceAvailabilityService;
import com.ruoyi.teacher.mapper.teacherMapper;
/**
 * 资源可用时间Service业务层处理
 * 
 * @author chenxl
 * @date 2025-06-29
 */
@Service
public class ResourceAvailabilityServiceImpl implements IResourceAvailabilityService 
{
    @Autowired
    private ResourceAvailabilityMapper resourceAvailabilityMapper;
    @Autowired
    private CourseStudentInfoMapper courseStudentInfoMapper;
    @Autowired
    private ClassScheduleDetailedMapper classScheduleDetailedMapper;
    //courseScheduleDetailsMapper
    @Autowired
    private CourseScheduleDetailsMapper courseScheduleDetailsMapper;
    @Autowired
    private teacherMapper teacherMapper;
    /**
     * 查询资源可用时间
     * 
     * @param id 资源可用时间主键
     * @return 资源可用时间
     */
    @Override
    public ResourceAvailability selectResourceAvailabilityById(String id)
    {
        return resourceAvailabilityMapper.selectResourceAvailabilityById(id);
    }

    /**
     * 查询资源可用时间列表
     * 
     * @param resourceAvailability 资源可用时间
     * @return 资源可用时间
     */
    @Override
    public List<ResourceAvailability> selectResourceAvailabilityList(ResourceAvailability resourceAvailability)
    {
        return resourceAvailabilityMapper.selectResourceAvailabilityList(resourceAvailability);
    }

    /**
     * 新增资源可用时间
     * 
     * @param resourceAvailability 资源可用时间
     * @return 结果
     */
    @Override
    public int insertResourceAvailability(ResourceAvailability resourceAvailability)
    {
        resourceAvailability.setId(UUID.randomUUID().toString());
        return resourceAvailabilityMapper.insertResourceAvailability(resourceAvailability);
    }

    /**
     * 修改资源可用时间
     * 
     * @param resourceAvailability 资源可用时间
     * @return 结果
     */
    @Override
    public int updateResourceAvailability(ResourceAvailability resourceAvailability)
    {
        return resourceAvailabilityMapper.updateResourceAvailability(resourceAvailability);
    }

    /**
     * 批量删除资源可用时间
     * 
     * @param ids 需要删除的资源可用时间主键
     * @return 结果
     */
    @Override
    public int deleteResourceAvailabilityByIds(String[] ids)
    {
        return resourceAvailabilityMapper.deleteResourceAvailabilityByIds(ids);
    }



    /**
     * 删除资源可用时间信息
     * 
     * @param id 资源可用时间主键
     * @return 结果
     */

    /**
     * 获取资源的完整课表
     * @param resourceId 资源ID
     * @param academicYear 学年
     * @return 结构化的课表数据
     */
    @Override
    public TimetableVO getResourceTimetable(String resourceId, String academicYear) {
        // 打印方法入参，确认资源ID和学年是否正确
        System.out.println("====== 开始查询资源时间表 ======");
        System.out.println("资源ID: " + resourceId + "，学年: " + academicYear);

        // 查询原始数据
        List<ResourceAvailability> availabilityList = resourceAvailabilityMapper.selectByResourceIdAndAcademicYear(resourceId, academicYear);

        // 打印原始数据总量和详细内容
        System.out.println("查询到的原始数据总量: " + (availabilityList == null ? 0 : availabilityList.size()));
        if (CollectionUtils.isNotEmpty(availabilityList)) {
            System.out.println("原始数据详情:");
            for (int i = 0; i < availabilityList.size(); i++) {
                ResourceAvailability item = availabilityList.get(i);
                System.out.println(
                        "  第" + (i + 1) + "条: dayOfWeek=" + item.getDayOfWeek() +
                                ", startTime=" + item.getStartTime() + ", endTime=" + item.getEndTime() +
                                ", reason=" + item.getReason() + ", semesterId=" + item.getSemesterId()
                );
            }
        }

        // 初始化课表
        TimetableVO timetable = new TimetableVO();
        timetable.setAcademicYear(academicYear);

        // 如果没有数据，直接返回空课表
        if (CollectionUtils.isEmpty(availabilityList)) {
            System.out.println("====== 无原始数据，返回空课表 ======");
            return timetable;
        }

        // 打印学期ID信息
        Long semesterId = availabilityList.get(0).getSemesterId();
        timetable.setSemesterId(semesterId);
        System.out.println("提取的学期ID: " + semesterId + "（取自第一条数据）");

        // 按周几分组
        Map<Integer, List<ResourceAvailability>> weekdayMap = availabilityList.stream()
                .filter(item -> {
                    // 打印过滤前的dayOfWeek，确认是否有异常值
                    String day = String.valueOf(item.getDayOfWeek());
                    System.out.println("过滤处理 - dayOfWeek原始值: " + day + "（是否有效: " + (day != null && day.matches("\\d+")) + "）");
                    return day != null && day.matches("\\d+"); // 仅保留数字格式的星期（1-7）
                })
                .collect(Collectors.groupingBy(item -> Integer.valueOf(item.getDayOfWeek())));

        // 打印周几分组结果
        System.out.println("按周几分组结果:");
        weekdayMap.forEach((weekday, items) -> {
            System.out.println("  星期" + weekday + "：共" + items.size() + "条数据");
        });

        // 构建周次数据
        for (int dayOfWeek = 1; dayOfWeek <= 7; dayOfWeek++) {
            System.out.println("\n====== 开始处理星期" + dayOfWeek + " ======");
            TimetableVO.Weekday weekday = new TimetableVO.Weekday();
            weekday.setDayOfWeek((long) dayOfWeek);

            // 获取当天的所有时间段
            List<ResourceAvailability> dayItems = weekdayMap.getOrDefault(dayOfWeek, Collections.emptyList());
            System.out.println("星期" + dayOfWeek + "的原始数据量: " + dayItems.size());

            // 按时间段分组（上午、下午、晚上）
            Map<String, List<ResourceAvailability>> timePeriodMap = dayItems.stream()
                    .collect(Collectors.groupingBy(item -> {
                        // 打印每个item的时间段分组依据
                        String period = getTimePeriod(item);
                        System.out.println("  时间段分组 - startTime=" + item.getStartTime() + "，被分到: " + period);
                        return period;
                    }));

            // 打印时间段分组结果
            System.out.println("星期" + dayOfWeek + "的时间段分组结果:");
            timePeriodMap.forEach((period, items) -> {
                System.out.println("  " + period + "：共" + items.size() + "条数据");
            });

            // 构建时间段数据
            for (String timePeriod : Arrays.asList("上午", "下午", "晚上")) {
                System.out.println("\n------ 处理" + timePeriod + "时间段 ------");
                TimetableVO.TimeSlot timeSlot = new TimetableVO.TimeSlot();
                timeSlot.setTimePeriod(timePeriod);

                // 获取该时间段的所有课程/占用
                List<ResourceAvailability> periodItems = timePeriodMap.getOrDefault(timePeriod, Collections.emptyList());
                System.out.println(timePeriod + "的待处理数据量: " + periodItems.size());

                // 构建课程/占用信息
                List<TimetableVO.CourseOccupancy> courses = periodItems.stream()
                        .map(item -> {
                            System.out.println("\n处理单条数据:");
                            System.out.println("  原始数据: dayOfWeek=" + item.getDayOfWeek() +
                                    ", startTime=" + item.getStartTime() +
                                    ", endTime=" + item.getEndTime());

                            // 解析节次（关键步骤打印）
                            int startLesson = 0;
                            int endLesson = 0;
                            try {
                                startLesson = parseLesson(item.getStartTime());
                                System.out.println("  解析startTime成功: " + item.getStartTime() + " → " + startLesson);
                            } catch (Exception e) {
                                System.out.println("  解析startTime失败: " + item.getStartTime() + "，错误: " + e.getMessage());
                            }
                            try {
                                endLesson = parseLesson(item.getEndTime());
                                System.out.println("  解析endTime成功: " + item.getEndTime() + " → " + endLesson);
                            } catch (Exception e) {
                                System.out.println("  解析endTime失败: " + item.getEndTime() + "，错误: " + e.getMessage());
                            }

                            TimetableVO.CourseOccupancy course = new TimetableVO.CourseOccupancy();
                            course.setStartLesson(startLesson);
                            course.setEndLesson(endLesson);
                            course.setTitle(item.getReason());
                            course.setLocation(item.getRemark());

                            Map<String, Object> extraInfo = new HashMap<>();
                            extraInfo.put("isAvailable", item.getIsAvailable());
                            extraInfo.put("creator", item.getCreatorId());
                            course.setExtraInfo(extraInfo);

                            System.out.println("  构建的课程信息: " + course);
                            return course;
                        })
                        .collect(Collectors.toList());

                timeSlot.setCourses(courses);
                System.out.println(timePeriod + "时间段最终课程数量: " + courses.size());
                weekday.getTimeSlots().add(timeSlot);
            }

            timetable.getWeekdays().add(weekday);
            System.out.println("====== 星期" + dayOfWeek + "处理完成 ======");
        }

        // 打印最终构建的时间表概要
        System.out.println("\n====== 时间表构建完成 ======");
        System.out.println("总周数: " + timetable.getWeekdays().size() +
                "，包含学期: " + timetable.getSemesterId() +
                "，学年: " + timetable.getAcademicYear());

        return timetable;
    }
    /**
     * 根据学生ID列表查询所有对应的课程表信息
     *
     * @param studentIds 学生ID列表
     * @return 结构化的课表数据
     */
    @Override
    public TimetableVO selectClassSchedulesByStudentIds(List<String> studentIds) {
        // 1. 校验参数
        if (studentIds == null || studentIds.isEmpty()) {
            throw new IllegalArgumentException("学生ID列表不能为空");
        }

        // 2. 查询课程排课ID
        List<String> courseScheduleIds = courseStudentInfoMapper.selectDistinctCourseScheduleIdsByStudentIds(studentIds);
        System.out.println("------------排课ID"+courseScheduleIds);

        // 3. 初始化课表并补充基础信息（根据实际业务补充，这里假设从第一个排课记录中获取）
        TimetableVO timetable = new TimetableVO();
        // 假设设置学年和学期（根据你的业务场景调整，例如从课程信息中获取）
        timetable.setAcademicYear("2024-2025"); // 示例值，需替换为实际逻辑
        timetable.setSemesterId(1L); // 示例值，需替换为实际逻辑

        // 4. 无排课数据则返回空课表
        if (CollectionUtils.isEmpty(courseScheduleIds)) {
            return timetable;
        }

        // 5. 查询课程表详细信息
        List<ClassScheduleDetailed> scheduleDetails = classScheduleDetailedMapper.selectByCourseScheduleDetailsIds(courseScheduleIds);
        System.out.println("------------排课结果"+scheduleDetails);

        // 6. 无详细排课信息则返回空课表
        if (CollectionUtils.isEmpty(scheduleDetails)) {
            return timetable;
        }

        // 7. 按周几分组（修复分组逻辑，确保weekDay不为null）
        Map<Long, List<ClassScheduleDetailed>> weekdayMap = scheduleDetails.stream()
                .filter(item -> item.getWeekDay() != null) // 过滤掉weekDay为null的记录
                .collect(Collectors.groupingBy(item -> item.getWeekDay().longValue()));

        // 8. 构建周次数据
        for (long dayOfWeek = 1; dayOfWeek <= 7; dayOfWeek++) {
            TimetableVO.Weekday weekday = new TimetableVO.Weekday();
            weekday.setDayOfWeek(dayOfWeek);

            // 获取当天的所有课程
            List<ClassScheduleDetailed> dayCourses = weekdayMap.getOrDefault(dayOfWeek, Collections.emptyList());

            // 按时间段分组（上午、下午、晚上）- 使用修正后的时间段判断逻辑
            Map<String, List<ClassScheduleDetailed>> timePeriodMap = dayCourses.stream()
                    .collect(Collectors.groupingBy(this::getTimePeriodForClass));

            // 9. 构建时间段数据（只处理上午、下午、晚上三个时间段）
            for (String timePeriod : Arrays.asList("上午", "下午", "晚上")) {
                TimetableVO.TimeSlot timeSlot = new TimetableVO.TimeSlot();
                timeSlot.setTimePeriod(timePeriod);

                // 获取该时间段的所有课程
                List<ClassScheduleDetailed> periodCourses = timePeriodMap.getOrDefault(timePeriod, Collections.emptyList());

                // 10. 构建课程信息
                List<TimetableVO.CourseOccupancy> courses = periodCourses.stream()
                        .map(item -> {
                            TimetableVO.CourseOccupancy course = new TimetableVO.CourseOccupancy();
                            // 解析节次（"第3节" → 3）
                            course.setStartLesson(parseLesson(item.getStartTime()));
                            course.setEndLesson(parseLesson(item.getEndTime()));
                            // 补充课程标题和地点（根据你的业务补充，这里仅为示例）
                            course.setTitle("课程名称"); // 需替换为实际课程名称获取逻辑
                            course.setLocation("教室位置"); // 需替换为实际教室获取逻辑

                            // 额外信息
                            Map<String, Object> extraInfo = new HashMap<>();
                            extraInfo.put("weekType", parseWeekType(item.getWeekType()));
                            extraInfo.put("lessonCount", item.getLessonCount());
                            extraInfo.put("courseScheduleDetailsId", item.getCourseScheduleDetailsId());
                            course.setExtraInfo(extraInfo);

                            return course;
                        })
                        .collect(Collectors.toList());

                timeSlot.setCourses(courses);
                weekday.getTimeSlots().add(timeSlot);
            }

            timetable.getWeekdays().add(weekday);
        }

        return timetable;
    }

    /**
     * 根据开始节次判断时间段（上午/下午/晚上）
     * @param item 资源占用记录（包含startTime，格式为“第X节”）
     * @return 时间段（上午/下午/晚上）
     */
    private String getTimePeriod(ResourceAvailability item) {
        String startTime = item.getStartTime();
        if (StringUtils.isEmpty(startTime)) {
            throw new IllegalArgumentException("开始时间不能为空: " + item);
        }

        // 步骤1：从“第X节”中提取节次数字（如“第5节”→5）
        int lesson;
        try {
            // 提取“第”和“节”之间的数字部分
            String numStr = startTime.substring(1, startTime.length() - 1); // “第5节”→“5”
            lesson = Integer.parseInt(numStr);
            System.out.println("解析startTime为节次: " + startTime + " → " + lesson);
        } catch (Exception e) {
            throw new RuntimeException("解析开始时间失败，格式应为“第X节”，实际为: " + startTime, e);
        }

        // 步骤2：根据节次判断时间段（可根据实际业务调整划分规则）
        if (lesson >= 1 && lesson <= 4) {
            return "上午";
        } else if (lesson >= 5 && lesson <= 8) {
            return "下午";
        } else if (lesson >= 9 && lesson <= 10) {
            return "晚上";
        } else {
            throw new IllegalArgumentException("节次超出范围（1-10）: " + lesson);
        }
    }

    private String getTimePeriodForClass(ClassScheduleDetailed item) {
        try {
            // 先解析startTime为节次（如"第3节" → 3）
            Integer lesson = parseLesson(item.getStartTime());
            if (lesson == null) {
                return "未知";
            }
            // 按节次划分时间段（可根据实际业务调整）
            if (lesson >= 1 && lesson <= 4) {
                return "上午";
            } else if (lesson >= 5 && lesson <= 8) {
                return "下午";
            } else if (lesson >= 9) {
                return "晚上";
            } else {
                return "未知";
            }
        } catch (Exception e) {
            System.err.println("解析课程时间段失败：" + e.getMessage());
            return "未知";
        }
    }

    // 辅助方法：解析节次
    private Integer parseLesson(String time) {
        if (time == null || time.isEmpty()) {
            return null;
        }
        // 处理"第3节"格式
        if (time.startsWith("第") && time.endsWith("节")) {
            String lessonStr = time.substring(1, time.length() - 1);
            return Integer.parseInt(lessonStr);
        }
        // 处理纯数字格式（如"3"）
        try {
            return Integer.parseInt(time);
        } catch (NumberFormatException e) {
            System.err.println("解析节次失败：" + time);
            return null;
        }
    }

    // 辅助方法：解析单双周类型 - 调整参数类型为Long以匹配实际使用
    private String parseWeekType(Long weekType) {
        if (weekType == null) return "全周";
        switch (weekType.intValue()) {  // 转换为int进行比较
            case 1: return "单周";
            case 2: return "双周";
            default: return "全周";
        }
    }

    /**
     * 根据课程安排详情ID查询学生ID列表
     *
     * @param courseScheduleDetailsId 课程安排详情ID
     * @return 学生ID列表
     */
    @Override
    public List<String> selectStudentIdsByCourseScheduleDetailsId(String courseScheduleDetailsId) {
        // 参数校验
        if (courseScheduleDetailsId == null || courseScheduleDetailsId.trim().isEmpty()) {
            return Collections.emptyList();
        }

        // 调用Mapper方法查询学生ID列表
        return resourceAvailabilityMapper.selectStudentIdsByCourseScheduleDetailsId(courseScheduleDetailsId);
    }
    @Override
    public int batchInsertResourceAvailability(List<ResourceAvailability> list) {
        return resourceAvailabilityMapper.batchInsert(list);
    }
    //selectByResourceIdAndResourceType
    @Override
    public List<ResourceAvailability> selectByResourceIdAndAcademicYear(String courseScheduleDetailsId, int academicYear) {
        return resourceAvailabilityMapper.selectByResourceIdAndResourceType(courseScheduleDetailsId, academicYear);
    }
    /**根据教师id查询对应的课表*/
    @Override
    public List<CourseSchedulingIinquiryVo> selectCourseSchedulingIinquiryListByTeacherId(String teacherId){
        int resourceType=1;
        List<String> courseScheduleDetailsIds = resourceAvailabilityMapper.selectCourseScheduleDetailsIdByResourceIdAndResourceType(teacherId,resourceType);
        System.out.println("获取到的排课ID为: " + courseScheduleDetailsIds);
        List<CourseSchedulingIinquiryVo> courseSchedulingIinquiryVos = new ArrayList<>();
        //遍历courseScheduleDetailsIds
        for (String courseScheduleDetailsId : courseScheduleDetailsIds) {
            CourseSchedulingIinquiryVo courseSchedulingIinquiryVo = new CourseSchedulingIinquiryVo();
            //resourceAvailabilityMapper.selectByResourceIdAndResourceType
            CourseScheduleDetails courseScheduleDetails  =courseScheduleDetailsMapper.selectById(courseScheduleDetailsId);
            List<ClassScheduleDetailed> classScheduleDetailes =classScheduleDetailedMapper.selectAllByCourseScheduleDetailsId(courseScheduleDetailsId);
            courseSchedulingIinquiryVo.setCourseScheduleDetails(courseScheduleDetails);
            courseSchedulingIinquiryVo.setClassScheduleDetailedList(classScheduleDetailes);
            courseSchedulingIinquiryVos.add(courseSchedulingIinquiryVo);
        }
        System.out.println("获取到的排课信息为: " + courseSchedulingIinquiryVos);
        return courseSchedulingIinquiryVos;
    }

    /**
     * 根据资源ID查询对应的课程安排详情ID列表
     * @param resourceId 资源ID
     * @return 课程安排详情ID列表
     */
    @Override
    public List<String> selectCourseScheduleDetailsIdByResourceId(String resourceId) {
        return resourceAvailabilityMapper.selectCourseScheduleDetailsIdsByResourceId(resourceId);
    }
    //根据teacher_code获取对应course_schedule_details_id列表
    @Override
    public List<CourseScheduleDetails> selectCourseScheduleDetailsIdByTeacherCode(String teacherCode) {
        String teacherId =teacherMapper.selectteacherIdByTeacherCode(teacherCode);
        if (teacherId == null || teacherId.trim().isEmpty()) {
            return Collections.emptyList(); // 教师不存在，返回空
        }

        // 2. 根据教师ID查询关联的 course_schedule_details_id 列表（原逻辑，可能返回空）
        List<String> courseScheduleDetailsIds = resourceAvailabilityMapper.selectCourseScheduleDetailsIdsByResourceId(teacherId);

        // 3. 核心修复：添加空列表校验，避免执行无效SQL
        if (CollectionUtils.isEmpty(courseScheduleDetailsIds)) {
            return Collections.emptyList(); // 无关联排课ID，直接返回空
        }

        // 4. 若列表非空，再查询排课详情（原逻辑，此时不会报错）
        return courseScheduleDetailsMapper.selectCourseScheduleDetailsByIds(courseScheduleDetailsIds);
    }
}
